﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Security.Cryptography;

namespace slimPickins.Tools.DownloadManager
{
    class DownloadManager
    {

        internal struct downloadQueueStruct
        {
            internal string Description { get; set; }
            internal string URL { get; set; }
            internal string downloadLocation { get; set; }
            internal string md5 { get; set; }
        }

        bool isDownloading = false;
        List<downloadQueueStruct> Queue = new List<downloadQueueStruct>();

        private void downloadFile(downloadQueueStruct Item)
        {
            isDownloading = true;

            WebClient wc = new WebClient();

            wc.DownloadFile(Item.URL, Item.downloadLocation);

        }

        static string GetMd5Hash(MD5 md5Hash, string inputFile)
        {

            FileStream fileStream = null;
            byte[] data = null;
            string result = "";

            try
            {
                fileStream = new FileStream(inputFile, FileMode.Open);

                // Convert the input string to a byte array and compute the hash.
                data = md5Hash.ComputeHash(fileStream);

                // Create a new Stringbuilder to collect the bytes
                // and create a string.
                StringBuilder sBuilder = new StringBuilder();

                // Loop through each byte of the hashed data 
                // and format each one as a hexadecimal string.
                for (int i = 0; i < data.Length; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }

                result = sBuilder.ToString();
            }
            catch
            {

            }
            finally
            {
                if(fileStream != null)
                    fileStream.Close();
            }

            // Return the hexadecimal string.
            return result;
        }

        // Verify a hash against a string.
        static bool VerifyMd5Hash(MD5 md5Hash, string inputFile, string hash)
        {
            // Hash the input.
            string hashOfInput = GetMd5Hash(md5Hash, inputFile);

            // Create a StringComparer an compare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private bool checkMD5(downloadQueueStruct Item)
        {
            bool result = false;

            if (Item.md5 != "0")
            {
                MD5 md5Hash = MD5.Create();

                result = VerifyMd5Hash(md5Hash, Item.downloadLocation, Item.md5);
            }

            return true;
        }

        public void addToQueue(string url, string Description, string md5)
        {
            downloadQueueStruct tmpDQ = new downloadQueueStruct();

            tmpDQ.Description = Description;
            tmpDQ.URL = url;
            tmpDQ.downloadLocation = ".\\" + Path.GetFileName(url);

            if (md5 != null || md5 != "")
            {
                tmpDQ.md5 = md5;
            }
            else
            {
                tmpDQ.md5 = "0";
            }

            Queue.Add(tmpDQ);

            startDownloadQueue();
        }

        public void startDownloadQueue()
        {
            if (!isDownloading)
            {
                for (int i = 0; i < Queue.Count(); i++)
                {
                    downloadFile(Queue[i]);

                    if(Queue[i].md5 != "0")
                        checkMD5(Queue[i]);
                }
            }
        }
    }
}
